home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / firefox-3.0.14 / components / nsBrowserGlue.js < prev    next >
Encoding:
Text File  |  2009-09-07  |  32.2 KB  |  857 lines

  1. //@line 39 "/build/buildd/firefox-3.0-3.0.14+build2+nobinonly/build-tree/mozilla/browser/components/nsBrowserGlue.js"
  2.  
  3. const Ci = Components.interfaces;
  4. const Cc = Components.classes;
  5. const Cr = Components.results;
  6. const Cu = Components.utils;
  7.  
  8. Cu.import("resource://gre/modules/XPCOMUtils.jsm");
  9. Cu.import("resource:///modules/distribution.js");
  10.  
  11. const PREF_EM_NEW_ADDONS_LIST = "extensions.newAddons";
  12.  
  13. // Check to see if bookmarks need backing up once per
  14. // day on 1 hour idle.
  15. const BOOKMARKS_ARCHIVE_IDLE_TIME = 60 * 60;
  16.  
  17. // Backup bookmarks once every 24 hours.
  18. const BOOKMARKS_ARCHIVE_INTERVAL = 86400 * 1000;
  19.  
  20. // Factory object
  21. const BrowserGlueServiceFactory = {
  22.   _instance: null,
  23.   createInstance: function (outer, iid) 
  24.   {
  25.     if (outer != null)
  26.       throw Components.results.NS_ERROR_NO_AGGREGATION;
  27.     return this._instance == null ?
  28.       this._instance = new BrowserGlue() : this._instance;
  29.   }
  30. };
  31.  
  32. // Constructor
  33.  
  34. function BrowserGlue() {
  35.   this._init();
  36. }
  37.  
  38. BrowserGlue.prototype = {
  39.   __prefs: null,
  40.   get _prefs() {
  41.     if (!this.__prefs)
  42.       this.__prefs = Cc["@mozilla.org/preferences-service;1"].
  43.                      getService(Ci.nsIPrefBranch);
  44.     return this.__prefs;
  45.   },
  46.  
  47.   _saveSession: false,
  48.  
  49.   _setPrefToSaveSession: function()
  50.   {
  51.     var prefBranch = Cc["@mozilla.org/preferences-service;1"].
  52.                      getService(Ci.nsIPrefBranch);
  53.     prefBranch.setBoolPref("browser.sessionstore.resume_session_once", true);
  54.   },
  55.  
  56.   // nsIObserver implementation 
  57.   observe: function(subject, topic, data) 
  58.   {
  59.     switch(topic) {
  60.       case "xpcom-shutdown":
  61.         this._dispose();
  62.         break;
  63.       case "quit-application": 
  64.         this._onProfileShutdown();
  65.         break;
  66.       case "prefservice:after-app-defaults":
  67.         this._onAppDefaults();
  68.         break;
  69.       case "final-ui-startup":
  70.         this._onProfileStartup();
  71.         break;
  72.       case "sessionstore-windows-restored":
  73.         this._onBrowserStartup();
  74.         break;
  75.       case "browser:purge-session-history":
  76.         // reset the console service's error buffer
  77.         const cs = Cc["@mozilla.org/consoleservice;1"].
  78.                    getService(Ci.nsIConsoleService);
  79.         cs.logStringMessage(null); // clear the console (in case it's open)
  80.         cs.reset();
  81.         break;
  82.       case "quit-application-requested":
  83.         this._onQuitRequest(subject, data);
  84.         break;
  85.       case "quit-application-granted":
  86.         if (this._saveSession) {
  87.           this._setPrefToSaveSession();
  88.         }
  89.         break;
  90.       case "session-save":
  91.         this._setPrefToSaveSession();
  92.         subject.QueryInterface(Ci.nsISupportsPRBool);
  93.         subject.data = true;
  94.         break;
  95.       case "idle":
  96.         if (this.idleService.idleTime > BOOKMARKS_ARCHIVE_IDLE_TIME * 1000) {
  97.           // Back up bookmarks.
  98.           this._archiveBookmarks();
  99.         }
  100.         break;
  101.     }
  102.   }, 
  103.  
  104.   // initialization (called on application startup) 
  105.   _init: function() 
  106.   {
  107.     // observer registration
  108.     const osvr = Cc['@mozilla.org/observer-service;1'].
  109.                  getService(Ci.nsIObserverService);
  110.     osvr.addObserver(this, "quit-application", false);
  111.     osvr.addObserver(this, "xpcom-shutdown", false);
  112.     osvr.addObserver(this, "prefservice:after-app-defaults", false);
  113.     osvr.addObserver(this, "final-ui-startup", false);
  114.     osvr.addObserver(this, "sessionstore-windows-restored", false);
  115.     osvr.addObserver(this, "browser:purge-session-history", false);
  116.     osvr.addObserver(this, "quit-application-requested", false);
  117.     osvr.addObserver(this, "quit-application-granted", false);
  118.     osvr.addObserver(this, "session-save", false);
  119.   },
  120.  
  121.   // cleanup (called on application shutdown)
  122.   _dispose: function() 
  123.   {
  124.     // observer removal 
  125.     const osvr = Cc['@mozilla.org/observer-service;1'].
  126.                  getService(Ci.nsIObserverService);
  127.     osvr.removeObserver(this, "quit-application");
  128.     osvr.removeObserver(this, "xpcom-shutdown");
  129.     osvr.removeObserver(this, "prefservice:after-app-defaults");
  130.     osvr.removeObserver(this, "final-ui-startup");
  131.     osvr.removeObserver(this, "sessionstore-windows-restored");
  132.     osvr.removeObserver(this, "browser:purge-session-history");
  133.     osvr.removeObserver(this, "quit-application-requested");
  134.     osvr.removeObserver(this, "quit-application-granted");
  135.     osvr.removeObserver(this, "session-save");
  136.   },
  137.  
  138.   _onAppDefaults: function()
  139.   {
  140.     // apply distribution customizations (prefs)
  141.     // other customizations are applied in _onProfileStartup()
  142.     var distro = new DistributionCustomizer();
  143.     distro.applyPrefDefaults();
  144.   },
  145.  
  146.   // profile startup handler (contains profile initialization routines)
  147.   _onProfileStartup: function() 
  148.   {
  149.     this.Sanitizer.onStartup();
  150.     // check if we're in safe mode
  151.     var app = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsIXULAppInfo).
  152.               QueryInterface(Ci.nsIXULRuntime);
  153.     if (app.inSafeMode) {
  154.       var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
  155.                getService(Ci.nsIWindowWatcher);
  156.       ww.openWindow(null, "chrome://browser/content/safeMode.xul", 
  157.                     "_blank", "chrome,centerscreen,modal,resizable=no", null);
  158.     }
  159.  
  160.     // initialize Places
  161.     this._initPlaces();
  162.  
  163.     // apply distribution customizations
  164.     // prefs are applied in _onAppDefaults()
  165.     var distro = new DistributionCustomizer();
  166.     distro.applyCustomizations();
  167.  
  168.     // handle any UI migration
  169.     this._migrateUI();
  170.  
  171.     const osvr = Cc['@mozilla.org/observer-service;1'].
  172.                  getService(Ci.nsIObserverService);
  173.     osvr.notifyObservers(null, "browser-ui-startup-complete", "");
  174.   },
  175.  
  176.   // profile shutdown handler (contains profile cleanup routines)
  177.   _onProfileShutdown: function() 
  178.   {
  179.     this._shutdownPlaces();
  180.     this.idleService.removeIdleObserver(this, BOOKMARKS_ARCHIVE_IDLE_TIME);
  181.     this.Sanitizer.onShutdown();
  182.   },
  183.  
  184.   // Browser startup complete. All initial windows have opened.
  185.   _onBrowserStartup: function()
  186.   {
  187.     // Show about:rights notification, if needed.
  188.     if (this._shouldShowRights())
  189.       this._showRightsNotification();
  190.  
  191.     var prefBranch = Cc["@mozilla.org/preferences-service;1"].
  192.                      getService(Ci.nsIPrefBranch);
  193.     // If new add-ons were installed during startup open the add-ons manager.
  194.     if (prefBranch.prefHasUserValue(PREF_EM_NEW_ADDONS_LIST)) {
  195.       var args = Cc["@mozilla.org/supports-array;1"].
  196.                  createInstance(Ci.nsISupportsArray);
  197.       var str = Cc["@mozilla.org/supports-string;1"].
  198.                 createInstance(Ci.nsISupportsString);
  199.       str.data = "";
  200.       args.AppendElement(str);
  201.       var str = Cc["@mozilla.org/supports-string;1"].
  202.                 createInstance(Ci.nsISupportsString);
  203.       str.data = prefBranch.getCharPref(PREF_EM_NEW_ADDONS_LIST);
  204.       args.AppendElement(str);
  205.       const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
  206.       const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable";
  207.       var ww = Cc["@mozilla.org/embedcomp/window-watcher;1"].
  208.                getService(Ci.nsIWindowWatcher);
  209.       ww.openWindow(null, EMURL, "_blank", EMFEATURES, args);
  210.       prefBranch.clearUserPref(PREF_EM_NEW_ADDONS_LIST);
  211.     }
  212.   },
  213.  
  214.   _onQuitRequest: function(aCancelQuit, aQuitType)
  215.   {
  216.     // If user has already dismissed quit request, then do nothing
  217.     if ((aCancelQuit instanceof Ci.nsISupportsPRBool) && aCancelQuit.data)
  218.       return;
  219.  
  220.     var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
  221.              getService(Ci.nsIWindowMediator);
  222.  
  223.     var windowcount = 0;
  224.     var pagecount = 0;
  225.     var browserEnum = wm.getEnumerator("navigator:browser");
  226.     while (browserEnum.hasMoreElements()) {
  227.       windowcount++;
  228.  
  229.       var browser = browserEnum.getNext();
  230.       var tabbrowser = browser.document.getElementById("content");
  231.       if (tabbrowser)
  232.         pagecount += tabbrowser.browsers.length;
  233.     }
  234.  
  235.     this._saveSession = false;
  236.     if (pagecount < 2)
  237.       return;
  238.  
  239.     if (aQuitType != "restart")
  240.       aQuitType = "quit";
  241.  
  242.     var prefBranch = Cc["@mozilla.org/preferences-service;1"].
  243.                      getService(Ci.nsIPrefBranch);
  244.     var showPrompt = true;
  245.     try {
  246.       // browser.warnOnQuit is a hidden global boolean to override all quit prompts
  247.       // browser.warnOnRestart specifically covers app-initiated restarts where we restart the app
  248.       // browser.tabs.warnOnClose is the global "warn when closing multiple tabs" pref
  249.  
  250.       var sessionWillBeSaved = prefBranch.getIntPref("browser.startup.page") == 3 ||
  251.                                prefBranch.getBoolPref("browser.sessionstore.resume_session_once");
  252.       if (sessionWillBeSaved || !prefBranch.getBoolPref("browser.warnOnQuit"))
  253.         showPrompt = false;
  254.       else if (aQuitType == "restart")
  255.         showPrompt = prefBranch.getBoolPref("browser.warnOnRestart");
  256.       else
  257.         showPrompt = prefBranch.getBoolPref("browser.tabs.warnOnClose");
  258.     } catch (ex) {}
  259.  
  260.     if (!showPrompt)
  261.       return false;
  262.  
  263.     var buttonChoice = 0;
  264.     var bundleService = Cc["@mozilla.org/intl/stringbundle;1"].
  265.                         getService(Ci.nsIStringBundleService);
  266.     var quitBundle = bundleService.createBundle("chrome://browser/locale/quitDialog.properties");
  267.     var brandBundle = bundleService.createBundle("chrome://branding/locale/brand.properties");
  268.  
  269.     var appName = brandBundle.GetStringFromName("brandShortName");
  270.     var quitDialogTitle = quitBundle.formatStringFromName(aQuitType + "DialogTitle",
  271.                                                             [appName], 1);
  272.  
  273.     var message;
  274.     if (aQuitType == "restart")
  275.       message = quitBundle.formatStringFromName("messageRestart",
  276.                                                 [appName], 1);
  277.     else if (windowcount == 1)
  278.       message = quitBundle.formatStringFromName("messageNoWindows",
  279.                                                 [appName], 1);
  280.     else
  281.       message = quitBundle.formatStringFromName("message",
  282.                                                 [appName], 1);
  283.  
  284.     var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].
  285.                         getService(Ci.nsIPromptService);
  286.  
  287.     var flags = promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0 +
  288.                 promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_1 +
  289.                 promptService.BUTTON_POS_0_DEFAULT;
  290.  
  291.     var neverAsk = {value:false};
  292.     var button0Title, button2Title;
  293.     var button1Title = quitBundle.GetStringFromName("cancelTitle");
  294.     var neverAskText = quitBundle.GetStringFromName("neverAsk");
  295.  
  296.     if (aQuitType == "restart")
  297.       button0Title = quitBundle.GetStringFromName("restartTitle");
  298.     else {
  299.       flags += promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_2;
  300.       button0Title = quitBundle.GetStringFromName("saveTitle");
  301.       button2Title = quitBundle.GetStringFromName("quitTitle");
  302.     }
  303.  
  304.     buttonChoice = promptService.confirmEx(null, quitDialogTitle, message,
  305.                                  flags, button0Title, button1Title, button2Title,
  306.                                  neverAskText, neverAsk);
  307.  
  308.     switch (buttonChoice) {
  309.     case 2: // Quit
  310.       if (neverAsk.value)
  311.         prefBranch.setBoolPref("browser.tabs.warnOnClose", false);
  312.       break;
  313.     case 1: // Cancel
  314.       aCancelQuit.QueryInterface(Ci.nsISupportsPRBool);
  315.       aCancelQuit.data = true;
  316.       break;
  317.     case 0: // Save & Quit
  318.       this._saveSession = true;
  319.       if (neverAsk.value) {
  320.         if (aQuitType == "restart")
  321.           prefBranch.setBoolPref("browser.warnOnRestart", false);
  322.         else {
  323.           // always save state when shutting down
  324.           prefBranch.setIntPref("browser.startup.page", 3);
  325.         }
  326.       }
  327.       break;
  328.     }
  329.   },
  330.  
  331.   /*
  332.    * _shouldShowRights - Determines if the user should be shown the
  333.    * about:rights notification. The notification should *not* be shown if
  334.    * we've already shown the current version, or if the override pref says to
  335.    * never show it. The notification *should* be shown if it's never been seen
  336.    * before, if a newer version is available, or if the override pref says to
  337.    * always show it.
  338.    */
  339.   _shouldShowRights : function () {
  340.     // Look for an unconditional override pref. If set, do what it says.
  341.     // (true --> never show, false --> always show)
  342.     try {
  343.       return !this._prefs.getBoolPref("browser.rights.override");
  344.     } catch (e) { }
  345.     // Ditto, for the legacy EULA pref.
  346.     try {
  347.       return !this._prefs.getBoolPref("browser.EULA.override");
  348.     } catch (e) { }
  349.  
  350. //@line 388 "/build/buildd/firefox-3.0-3.0.14+build2+nobinonly/build-tree/mozilla/browser/components/nsBrowserGlue.js"
  351.     // Non-official builds shouldn't shouldn't show the notification.
  352.     return false;
  353. //@line 391 "/build/buildd/firefox-3.0-3.0.14+build2+nobinonly/build-tree/mozilla/browser/components/nsBrowserGlue.js"
  354.  
  355.     // Look to see if the user has seen the current version or not.
  356.     var currentVersion = this._prefs.getIntPref("browser.rights.version");
  357.     try {
  358.       return !this._prefs.getBoolPref("browser.rights." + currentVersion + ".shown");
  359.     } catch (e) { }
  360.  
  361.     // Legacy: If the user accepted a EULA, we won't annoy them with the
  362.     // equivalent about:rights page until the version changes.
  363.     try {
  364.       return !this._prefs.getBoolPref("browser.EULA." + currentVersion + ".accepted");
  365.     } catch (e) { }
  366.  
  367.     // We haven't shown the notification before, so do so now.
  368.     return true;
  369.   },
  370.  
  371.   _showRightsNotification : function () {
  372.     // Stick the notification onto the selected tab of the active browser window.
  373.     var win = this._getMostRecentBrowserWindow();
  374.     var browser = win.gBrowser; // for closure in notification bar callback
  375.     var notifyBox = browser.getNotificationBox();
  376.  
  377.     var bundleService = Cc["@mozilla.org/intl/stringbundle;1"].
  378.                         getService(Ci.nsIStringBundleService);
  379.     var brandBundle  = bundleService.createBundle("chrome://branding/locale/brand.properties");
  380.     var rightsBundle = bundleService.createBundle("chrome://browser/locale/aboutRights.properties");
  381.  
  382.     var buttonLabel     = rightsBundle.GetStringFromName("buttonLabel");
  383.     var buttonAccessKey = rightsBundle.GetStringFromName("buttonAccessKey");
  384.     var productName     = brandBundle.GetStringFromName("brandFullName");
  385.     var notifyText      = rightsBundle.formatStringFromName("notifyText", [productName], 1);
  386.     
  387.     var buttons = [
  388.                     {
  389.                       label:     buttonLabel,
  390.                       accessKey: buttonAccessKey,
  391.                       popup:     null,
  392.                       callback: function(aNotificationBar, aButton) {
  393.                         browser.selectedTab = browser.addTab("about:rights");
  394.                       }
  395.                     }
  396.                   ];
  397.  
  398.     // Set pref to indicate we've shown the notification.
  399.     var currentVersion = this._prefs.getIntPref("browser.rights.version");
  400.     this._prefs.setBoolPref("browser.rights." + currentVersion + ".shown", true);
  401.  
  402.     var box = notifyBox.appendNotification(notifyText, "about-rights", null, notifyBox.PRIORITY_INFO_LOW, buttons);
  403.     box.persistence = 3; // // arbitrary number, just so bar sticks around for a bit
  404.   },
  405.  
  406.   // returns the (cached) Sanitizer constructor
  407.   get Sanitizer() 
  408.   {
  409.     if(typeof(Sanitizer) != "function") { // we should dynamically load the script
  410.       Cc["@mozilla.org/moz/jssubscript-loader;1"].
  411.       getService(Ci.mozIJSSubScriptLoader).
  412.       loadSubScript("chrome://browser/content/sanitize.js", null);
  413.     }
  414.     return Sanitizer;
  415.   },
  416.  
  417.   _idleService: null,
  418.   get idleService() {
  419.     if (!this._idleService)
  420.       this._idleService = Cc["@mozilla.org/widget/idleservice;1"].
  421.                           getService(Ci.nsIIdleService);
  422.     return this._idleService;
  423.   },
  424.  
  425.   /**
  426.    * Initialize Places
  427.    * - imports the bookmarks html file if bookmarks datastore is empty
  428.    *
  429.    * These prefs are set by the backend services upon creation (or recreation)
  430.    * of the Places db:
  431.    * - browser.places.importBookmarksHTML
  432.    *   Set to false by the history service to indicate we need to re-import.
  433.    * - browser.places.smartBookmarksVersion
  434.    *   Set during HTML import to indicate that Smart Bookmarks were created.
  435.    *   Set to -1 to disable Smart Bookmarks creation.
  436.    *   Set to 0 to restore current Smart Bookmarks.
  437.    *
  438.    * These prefs are set up by the frontend:
  439.    * - browser.bookmarks.restore_default_bookmarks
  440.    *   Set to true by safe-mode dialog to indicate we must restore default
  441.    *   bookmarks.
  442.    */
  443.   _initPlaces: function bg__initPlaces() {
  444.     // we need to instantiate the history service before checking
  445.     // the browser.places.importBookmarksHTML pref, as
  446.     // nsNavHistory::ForceMigrateBookmarksDB() will set that pref
  447.     // if we need to force a migration (due to a schema change)
  448.     var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
  449.                   getService(Ci.nsINavHistoryService);
  450.  
  451.     var prefBranch = Cc["@mozilla.org/preferences-service;1"].
  452.                      getService(Ci.nsIPrefBranch);
  453.  
  454.     var importBookmarks = false;
  455.     var importBookmarksHTML = false;
  456.     var restoreDefaultBookmarks = false;
  457.     try {
  458.       restoreDefaultBookmarks = prefBranch.getBoolPref("browser.bookmarks.restore_default_bookmarks");
  459.     } catch(ex) {}
  460.  
  461.     if (restoreDefaultBookmarks) {
  462.       // Ensure that we already have a bookmarks backup for today
  463.       this._archiveBookmarks();
  464.       // we will restore bookmarks from html
  465.       importBookmarks = true;
  466.     }
  467.     else {
  468.       try {
  469.         importBookmarks = importBookmarksHTML =
  470.           prefBranch.getBoolPref("browser.places.importBookmarksHTML");
  471.       } catch(ex) {}
  472.     }
  473.  
  474.     if (!importBookmarks) {
  475.       // Call it here for Fx3 profiles created before the Places folder
  476.       // has been added, otherwise it's called during import.
  477.       this.ensurePlacesDefaultQueriesInitialized();
  478.     }
  479.     else {
  480.       // get latest backup
  481.       Cu.import("resource://gre/modules/utils.js");
  482.       var bookmarksFile = PlacesUtils.getMostRecentBackup();
  483.  
  484.       if (!restoreDefaultBookmarks &&
  485.           bookmarksFile && bookmarksFile.leafName.match("\.json$")) {
  486.         // restore a JSON backup
  487.         PlacesUtils.restoreBookmarksFromJSONFile(bookmarksFile);
  488.       }
  489.       else {
  490.         // if there's no JSON backup or we are restoring default bookmarks
  491.  
  492.         // ensurePlacesDefaultQueriesInitialized() is called by import.
  493.         prefBranch.setIntPref("browser.places.smartBookmarksVersion", 0);
  494.  
  495.         var dirService = Cc["@mozilla.org/file/directory_service;1"].
  496.                          getService(Ci.nsIProperties);
  497.  
  498.         var bookmarksFile = dirService.get("BMarks", Ci.nsILocalFile);
  499.         if (restoreDefaultBookmarks || !bookmarksFile.exists()) {
  500.           // get bookmarks.html file from default profile folder
  501.           bookmarksFile = dirService.get("profDef", Ci.nsILocalFile);
  502.           bookmarksFile.append("bookmarks.html");
  503.         }
  504.  
  505.         // import the file
  506.         try {
  507.           var importer = Cc["@mozilla.org/browser/places/import-export-service;1"].
  508.                          getService(Ci.nsIPlacesImportExportService);
  509.           importer.importHTMLFromFile(bookmarksFile, true /* overwrite existing */);
  510.         } catch (err) {
  511.           // Report the error, but ignore it.
  512.           Cu.reportError(err);
  513.         }
  514.       }
  515.       if (importBookmarksHTML)
  516.         prefBranch.setBoolPref("browser.places.importBookmarksHTML", false);
  517.       if (restoreDefaultBookmarks)
  518.         prefBranch.setBoolPref("browser.bookmarks.restore_default_bookmarks",
  519.                                false);
  520.     }
  521.  
  522.     // Initialize bookmark archiving on idle.
  523.     // Once a day, either on idle or shutdown, bookmarks are backed up.
  524.     this.idleService.addIdleObserver(this, BOOKMARKS_ARCHIVE_IDLE_TIME);
  525.   },
  526.  
  527.   /**
  528.    * Places shut-down tasks
  529.    * - back up and archive bookmarks
  530.    * - export bookmarks as HTML, if so configured
  531.    *
  532.    * Note: quit-application-granted notification is received twice
  533.    *       so replace this method with a no-op when first called.
  534.    */
  535.   _shutdownPlaces: function bg__shutdownPlaces() {
  536.     // Backup and archive Places bookmarks.
  537.     this._archiveBookmarks();
  538.  
  539.     // Backup bookmarks to bookmarks.html to support apps that depend
  540.     // on the legacy format.
  541.     var prefs = Cc["@mozilla.org/preferences-service;1"].
  542.                 getService(Ci.nsIPrefBranch);
  543.     var autoExportHTML = false;
  544.     try {
  545.       autoExportHTML = prefs.getBoolPref("browser.bookmarks.autoExportHTML");
  546.     } catch(ex) {
  547.       Components.utils.reportError(ex);
  548.     }
  549.  
  550.     if (autoExportHTML) {
  551.       Cc["@mozilla.org/browser/places/import-export-service;1"].
  552.         getService(Ci.nsIPlacesImportExportService).
  553.         backupBookmarksFile();
  554.     }
  555.   },
  556.  
  557.   /**
  558.    * Back up and archive bookmarks
  559.    */
  560.   _archiveBookmarks: function nsBrowserGlue__archiveBookmarks() {
  561.     Cu.import("resource://gre/modules/utils.js");
  562.  
  563.     var lastBackup = PlacesUtils.getMostRecentBackup();
  564.  
  565.     // Backup bookmarks if there aren't any backups or 
  566.     // they haven't been backed up in the last 24 hrs.
  567.     if (!lastBackup ||
  568.         Date.now() - lastBackup.lastModifiedTime > BOOKMARKS_ARCHIVE_INTERVAL) {
  569.       var maxBackups = 5;
  570.       var prefs = Cc["@mozilla.org/preferences-service;1"].
  571.                   getService(Ci.nsIPrefBranch);
  572.       try {
  573.         maxBackups = prefs.getIntPref("browser.bookmarks.max_backups");
  574.       } catch(ex) {}
  575.  
  576.       PlacesUtils.archiveBookmarksFile(maxBackups, false /* don't force */);
  577.     }
  578.   },
  579.  
  580.   _migrateUI: function bg__migrateUI() {
  581.     var prefBranch = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
  582.  
  583.     var migration = 0;
  584.     try {
  585.       migration = prefBranch.getIntPref("browser.migration.version");
  586.     } catch(ex) {}
  587.  
  588.     if (migration == 0) {
  589.       // this code should always migrate pre-FF3 profiles to the current UI state
  590.  
  591.       // grab the localstore.rdf and make changes needed for new UI
  592.       this._rdf = Cc["@mozilla.org/rdf/rdf-service;1"].getService(Ci.nsIRDFService);
  593.       this._dataSource = this._rdf.GetDataSource("rdf:local-store");
  594.       this._dirty = false;
  595.  
  596.       let currentsetResource = this._rdf.GetResource("currentset");
  597.       let toolbars = ["nav-bar", "toolbar-menubar", "PersonalToolbar"];
  598.       for (let i = 0; i < toolbars.length; i++) {
  599.         let toolbar = this._rdf.GetResource("chrome://browser/content/browser.xul#" + toolbars[i]);
  600.         let currentset = this._getPersist(toolbar, currentsetResource);
  601.         if (!currentset) {
  602.           // toolbar isn't customized
  603.           if (i == 0)
  604.             // new button is in the defaultset, nothing to migrate
  605.             break;
  606.           continue;
  607.         }
  608.         if (/(?:^|,)unified-back-forward-button(?:$|,)/.test(currentset))
  609.           // new button is already there, nothing to migrate
  610.           break;
  611.         if (/(?:^|,)back-button(?:$|,)/.test(currentset)) {
  612.           let newset = currentset.replace(/(^|,)back-button($|,)/,
  613.                                           "$1unified-back-forward-button,back-button$2")
  614.           this._setPersist(toolbar, currentsetResource, newset);
  615.           // done migrating
  616.           break;
  617.         }
  618.       }
  619.  
  620.       // force the RDF to be saved
  621.       if (this._dirty)
  622.         this._dataSource.QueryInterface(Ci.nsIRDFRemoteDataSource).Flush();
  623.  
  624.       // free up the RDF service
  625.       this._rdf = null;
  626.       this._dataSource = null;
  627.  
  628.       // update the migration version
  629.       prefBranch.setIntPref("browser.migration.version", 1);
  630.     }
  631.   },
  632.  
  633.   _getPersist: function bg__getPersist(aSource, aProperty) {
  634.     var target = this._dataSource.GetTarget(aSource, aProperty, true);
  635.     if (target instanceof Ci.nsIRDFLiteral)
  636.       return target.Value;
  637.     return null;
  638.   },
  639.  
  640.   _setPersist: function bg__setPersist(aSource, aProperty, aTarget) {
  641.     this._dirty = true;
  642.     try {
  643.       var oldTarget = this._dataSource.GetTarget(aSource, aProperty, true);
  644.       if (oldTarget) {
  645.         if (aTarget)
  646.           this._dataSource.Change(aSource, aProperty, oldTarget, this._rdf.GetLiteral(aTarget));
  647.         else
  648.           this._dataSource.Unassert(aSource, aProperty, oldTarget);
  649.       }
  650.       else {
  651.         this._dataSource.Assert(aSource, aProperty, this._rdf.GetLiteral(aTarget), true);
  652.       }
  653.     }
  654.     catch(ex) {}
  655.   },
  656.  
  657.   // ------------------------------
  658.   // public nsIBrowserGlue members
  659.   // ------------------------------
  660.   
  661.   sanitize: function(aParentWindow) 
  662.   {
  663.     this.Sanitizer.sanitize(aParentWindow);
  664.   },
  665.  
  666.   ensurePlacesDefaultQueriesInitialized: function() {
  667.     const SMART_BOOKMARKS_VERSION = 1;
  668.     const SMART_BOOKMARKS_ANNO = "Places/SmartBookmark";
  669.     const SMART_BOOKMARKS_PREF = "browser.places.smartBookmarksVersion";
  670.  
  671.     // XXX should this be a pref?  see bug #399268
  672.     const MAX_RESULTS = 10;
  673.  
  674.     var prefBranch = Cc["@mozilla.org/preferences-service;1"].
  675.                      getService(Ci.nsIPrefBranch);
  676.  
  677.     // get current smart bookmarks version
  678.     // By default, if the pref is not set up, we must create Smart Bookmarks
  679.     var smartBookmarksCurrentVersion = 0;
  680.     try {
  681.       smartBookmarksCurrentVersion = prefBranch.getIntPref(SMART_BOOKMARKS_PREF);
  682.     } catch(ex) {}
  683.  
  684.     // bail out if we don't have to create or update Smart Bookmarks
  685.     if (smartBookmarksCurrentVersion == -1 ||
  686.         smartBookmarksCurrentVersion >= SMART_BOOKMARKS_VERSION)
  687.       return;
  688.  
  689.     var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
  690.                 getService(Ci.nsINavBookmarksService);
  691.     var annosvc = Cc["@mozilla.org/browser/annotation-service;1"].
  692.                   getService(Ci.nsIAnnotationService);
  693.  
  694.     var callback = {
  695.       _placesBundle: Cc["@mozilla.org/intl/stringbundle;1"].
  696.                      getService(Ci.nsIStringBundleService).
  697.                      createBundle("chrome://browser/locale/places/places.properties"),
  698.  
  699.       _uri: function(aSpec) {
  700.         return Cc["@mozilla.org/network/io-service;1"].
  701.                getService(Ci.nsIIOService).
  702.                newURI(aSpec, null, null);
  703.       },
  704.  
  705.       runBatched: function() {
  706.         var smartBookmarks = [];
  707.         var bookmarksMenuIndex = 0;
  708.         var bookmarksToolbarIndex = 0;
  709.  
  710.         // MOST VISITED
  711.         var smart = {queryId: "MostVisited", // don't change this
  712.                      itemId: null,
  713.                      title: this._placesBundle.GetStringFromName("mostVisitedTitle"),
  714.                      uri: this._uri("place:queryType=" +
  715.                                     Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY +
  716.                                     "&sort=" +
  717.                                     Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
  718.                                     "&maxResults=" + MAX_RESULTS),
  719.                      parent: bmsvc.toolbarFolder,
  720.                      position: bookmarksToolbarIndex++};
  721.         smartBookmarks.push(smart);
  722.  
  723.         // RECENTLY BOOKMARKED
  724.         smart = {queryId: "RecentlyBookmarked", // don't change this
  725.                  itemId: null,
  726.                  title: this._placesBundle.GetStringFromName("recentlyBookmarkedTitle"),
  727.                  uri: this._uri("place:folder=BOOKMARKS_MENU" +
  728.                                 "&folder=UNFILED_BOOKMARKS" +
  729.                                 "&folder=TOOLBAR" +
  730.                                 "&queryType=" +
  731.                                 Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
  732.                                 "&sort=" +
  733.                                 Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
  734.                                 "&excludeItemIfParentHasAnnotation=livemark%2FfeedURI" +
  735.                                 "&maxResults=" + MAX_RESULTS +
  736.                                 "&excludeQueries=1"),
  737.                  parent: bmsvc.bookmarksMenuFolder,
  738.                  position: bookmarksMenuIndex++};
  739.         smartBookmarks.push(smart);
  740.  
  741.         // RECENT TAGS
  742.         smart = {queryId: "RecentTags", // don't change this
  743.                  itemId: null,
  744.                  title: this._placesBundle.GetStringFromName("recentTagsTitle"),
  745.                  uri: this._uri("place:"+
  746.                     "type=" +
  747.                     Ci.nsINavHistoryQueryOptions.RESULTS_AS_TAG_QUERY +
  748.                     "&sort=" +
  749.                     Ci.nsINavHistoryQueryOptions.SORT_BY_LASTMODIFIED_DESCENDING +
  750.                     "&maxResults=" + MAX_RESULTS),
  751.                  parent: bmsvc.bookmarksMenuFolder,
  752.                  position: bookmarksMenuIndex++};
  753.         smartBookmarks.push(smart);
  754.  
  755.         var smartBookmarkItemIds = annosvc.getItemsWithAnnotation(SMART_BOOKMARKS_ANNO, {});
  756.         // set current itemId, parent and position if Smart Bookmark exists
  757.         for each(var itemId in smartBookmarkItemIds) {
  758.           var queryId = annosvc.getItemAnnotation(itemId, SMART_BOOKMARKS_ANNO);
  759.           for (var i = 0; i < smartBookmarks.length; i++){
  760.             if (smartBookmarks[i].queryId == queryId) {
  761.               smartBookmarks[i].itemId = itemId;
  762.               smartBookmarks[i].parent = bmsvc.getFolderIdForItem(itemId);
  763.               smartBookmarks[i].position = bmsvc.getItemIndex(itemId);
  764.               // remove current item, since it will be replaced
  765.               bmsvc.removeItem(itemId);
  766.               break;
  767.             }
  768.             // We don't remove old Smart Bookmarks because user could still
  769.             // find them useful, or could have personalized them.
  770.             // Instead we remove the Smart Bookmark annotation.
  771.             if (i == smartBookmarks.length - 1)
  772.               annosvc.removeItemAnnotation(itemId, SMART_BOOKMARKS_ANNO);
  773.           }
  774.         }
  775.  
  776.         // create smart bookmarks
  777.         for each(var smartBookmark in smartBookmarks) {
  778.           smartBookmark.itemId = bmsvc.insertBookmark(smartBookmark.parent,
  779.                                                       smartBookmark.uri,
  780.                                                       smartBookmark.position,
  781.                                                       smartBookmark.title);
  782.           annosvc.setItemAnnotation(smartBookmark.itemId,
  783.                                     SMART_BOOKMARKS_ANNO, smartBookmark.queryId,
  784.                                     0, annosvc.EXPIRE_NEVER);
  785.         }
  786.         
  787.         // If we are creating all Smart Bookmarks from ground up, add a
  788.         // separator below them in the bookmarks menu.
  789.         if (smartBookmarkItemIds.length == 0)
  790.           bmsvc.insertSeparator(bmsvc.bookmarksMenuFolder, bookmarksMenuIndex);
  791.       }
  792.     };
  793.  
  794.     try {
  795.       bmsvc.runInBatchMode(callback, null);
  796.     }
  797.     catch(ex) {
  798.       Components.utils.reportError(ex);
  799.     }
  800.     finally {
  801.       prefBranch.setIntPref(SMART_BOOKMARKS_PREF, SMART_BOOKMARKS_VERSION);
  802.       prefBranch.QueryInterface(Ci.nsIPrefService).savePrefFile(null);
  803.     }
  804.   },
  805.  
  806. //@line 851 "/build/buildd/firefox-3.0-3.0.14+build2+nobinonly/build-tree/mozilla/browser/components/nsBrowserGlue.js"
  807.  
  808.   // this returns the most recent non-popup browser window
  809.   _getMostRecentBrowserWindow : function ()
  810.   {
  811.     var wm = Cc["@mozilla.org/appshell/window-mediator;1"].
  812.              getService(Components.interfaces.nsIWindowMediator);
  813.  
  814. //@line 859 "/build/buildd/firefox-3.0-3.0.14+build2+nobinonly/build-tree/mozilla/browser/components/nsBrowserGlue.js"
  815.     var win = wm.getMostRecentWindow("navigator:browser", true);
  816.  
  817.     // if we're lucky, this isn't a popup, and we can just return this
  818.     if (win && win.document.documentElement.getAttribute("chromehidden")) {
  819.       win = null;
  820.       var windowList = wm.getEnumerator("navigator:browser", true);
  821.       // this is oldest to newest, so this gets a bit ugly
  822.       while (windowList.hasMoreElements()) {
  823.         var nextWin = windowList.getNext();
  824.         if (!nextWin.document.documentElement.getAttribute("chromehidden"))
  825.           win = nextWin;
  826.       }
  827.     }
  828. //@line 885 "/build/buildd/firefox-3.0-3.0.14+build2+nobinonly/build-tree/mozilla/browser/components/nsBrowserGlue.js"
  829.  
  830.     return win;
  831.   },
  832.  
  833.   // for XPCOM
  834.   classDescription: "Firefox Browser Glue Service",
  835.   classID:          Components.ID("{eab9012e-5f74-4cbc-b2b5-a590235513cc}"),
  836.   contractID:       "@mozilla.org/browser/browserglue;1",
  837.  
  838.   QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver,
  839.                                          Ci.nsISupportsWeakReference,
  840.                                          Ci.nsIBrowserGlue]),
  841.  
  842.   // redefine the default factory for XPCOMUtils
  843.   _xpcom_factory: BrowserGlueServiceFactory,
  844.  
  845.   // get this contractID registered for certain categories via XPCOMUtils
  846.   _xpcom_categories: [
  847.     // make BrowserGlue a startup observer
  848.     { category: "app-startup", service: true }
  849.   ]
  850. }
  851.  
  852. //module initialization
  853. function NSGetModule(aCompMgr, aFileSpec) {
  854.   return XPCOMUtils.generateModule([BrowserGlue]);
  855. }
  856.  
  857.